package codec

import (
	"bufio"
	"bytes"
	"compress/flate"
	"encoding/binary"
	"encoding/gob"
	"errors"
	"io"
	"log"
	"net/rpc"
	"runtime/debug"
	"sync"
	"time"
)

// ================== 核心数据结构 ==================
const (
	headerSize    = 4 // 长度前缀字节数
	maxBufferSize = 4 * 1024 * 1024
)

var (
	// 全局内存池减少GC压力
	bufferPool = sync.Pool{
		New: func() interface{} {
			return bytes.NewBuffer(make([]byte, 0, 8192))
		},
	}

	// 压缩器池 (线程安全)
	compressWriterPool = sync.Pool{
		New: func() interface{} {
			w, _ := flate.NewWriter(nil, flate.BestSpeed)
			return w
		},
	}
)

// 带压缩功能的Gob编解码器
type CompressedGobCodec struct {
	conn    io.ReadWriteCloser
	br      *bufio.Reader
	bw      *bufio.Writer
	encLock sync.Mutex // 编码锁

	// 动态压缩级别配置
	compLevel   int
	lastLatency time.Duration

	// 统计相关字段
	stats struct {
		sync.Mutex // 保护并发更新

		// 压缩统计
		totalRequests       uint64
		compressedRequests  uint64
		rawRequests         uint64
		bytesSaved          uint64
		compressionTime     time.Duration
		totalProcessingTime time.Duration
		compressionFailed   uint64

		// 网络指标
		networkWriteTime  time.Duration
		networkWriteBytes uint64
		networkReadTime   time.Duration
		networkReadBytes  uint64

		// 延迟相关
		lastLatency    time.Duration
		avgLatency     time.Duration
		maxLatency     time.Duration
		latencySamples uint64

		// 压缩决策分布
		decisionCount [3]uint64 // 0:raw, 1:low, 2:high

		count          uint64
		totalSize      uint64
		compressedSize uint64
		processingTime time.Duration
		cpuUsage       float64 // %
	}

	// 策略相关
	rawThreshold     int // 原始阈值
	lowCompThreshold int // 低压缩阈值
}

// ================== 构造函数 ==================
func NewCompressedGobCodec(conn io.ReadWriteCloser, compressionLevel int) *CompressedGobCodec {

	if conn == nil {
		panic("connection not initialized")
	}

	if compressionLevel < flate.NoCompression || compressionLevel > flate.BestCompression {
		compressionLevel = flate.BestSpeed
	}

	return &CompressedGobCodec{
		conn:             conn,
		br:               bufio.NewReaderSize(conn, 32*1024),
		bw:               bufio.NewWriterSize(conn, 32*1024),
		compLevel:        compressionLevel,
		rawThreshold:     512,
		lowCompThreshold: 8192,
	}
}

// writeRaw 实现未压缩数据写入
func (c *CompressedGobCodec) writeRaw(data []byte) error {
	if c == nil || c.br == nil || c.conn == nil {
		return errors.New("codec or reader not initialized")
	}

	start := time.Now()
	sizeBefore := len(data)

	// 写入未压缩标记 + 数据长度
	header := make([]byte, headerSize+1)
	header[0] = 0x00 // 未压缩标记
	binary.BigEndian.PutUint32(header[1:], uint32(len(data)))

	// 原子写入
	if _, err := c.bw.Write(header); err != nil {
		return err
	}
	_, err := c.bw.Write(data)
	if err != nil {
		return err
	}

	// 更新统计
	sizeAfter := headerSize + 1 + sizeBefore // 头部+数据

	c.stats.Lock()
	c.stats.rawRequests++
	c.stats.totalRequests++
	c.stats.networkWriteBytes += uint64(sizeAfter)
	c.stats.networkWriteTime += time.Since(start)

	// 记录决策类型
	c.stats.decisionCount[0]++ // raw
	c.stats.Unlock()

	return err
}

// compress 实现数据压缩
func (c *CompressedGobCodec) compress(data []byte, level int) error {
	if c == nil || c.br == nil || c.conn == nil {
		return errors.New("codec or reader not initialized")
	}
	start := time.Now()
	sizeBefore := len(data)
	// 获取压缩器并重置
	compressor := compressWriterPool.Get().(*flate.Writer)
	defer compressWriterPool.Put(compressor)
	if compressor == nil || level != c.compLevel {
		// 如果池中没有可用的压缩器或级别不匹配，创建新的并指定级别
		compressor, _ = flate.NewWriter(c.bw, level)
	} else {
		// 重置现有压缩器
		compressor.Reset(c.bw)
	}
	// 创建压缩缓冲区
	compBuffer := bufferPool.Get().(*bytes.Buffer)
	defer bufferPool.Put(compBuffer)
	compBuffer.Reset()

	// 先写入压缩标记+原始长度
	header := make([]byte, headerSize+1)
	header[0] = 0x01 // 压缩标记
	binary.BigEndian.PutUint32(header[1:], uint32(len(data)))

	// 压缩数据
	compressor.Reset(compBuffer)
	if _, err := compressor.Write(data); err != nil {
		return err
	}
	if err := compressor.Flush(); err != nil {
		return err
	}

	// 验证压缩效果（避免负压缩）
	compressed := compBuffer.Bytes()
	if len(compressed)+headerSize+1 >= len(data) {
		// 压缩后体积更大，回退到原始数据
		return c.writeRaw(data)
	}

	// 写入压缩头
	if _, err := c.bw.Write(header); err != nil {
		return err
	}

	// 写入压缩数据
	_, err := c.bw.Write(compressed)
	if err != nil {
		return err
	}

	// 更新统计
	duration := time.Since(start)
	sizeAfter := headerSize + 1 + len(compressed)

	c.stats.Lock()
	c.stats.compressedRequests++
	c.stats.bytesSaved += uint64(sizeBefore - sizeAfter)
	c.stats.compressionTime += duration
	c.stats.networkWriteBytes += uint64(sizeAfter)
	c.stats.totalRequests++

	// 记录决策类型
	if len(data) < c.rawThreshold {
		c.stats.decisionCount[0]++ // raw
	} else if len(data) < c.lowCompThreshold {
		c.stats.decisionCount[1]++ // low
	} else {
		c.stats.decisionCount[2]++ // high
	}
	c.stats.Unlock()

	return nil
}

// adaptiveCompress 智能压缩决策
func (c *CompressedGobCodec) adaptiveCompress(data []byte) error {
	switch {
	case len(data) < 512:
		// 小包不压缩
		return c.writeRaw(data)

	case len(data) < 8192:
		// 中等包快速压缩
		return c.compress(data, flate.BestSpeed)

	default:
		// 大包高压缩率（根据网络质量调整）
		level := c.adjustLevel(c.lastLatency)
		return c.compress(data, level)
	}
}

// adjustLevel 基于网络延迟动态调整压缩级别
func (c *CompressedGobCodec) adjustLevel(latency time.Duration) int {
	// 默认使用初始配置级别
	if latency == 0 {
		return c.compLevel
	}

	// 动态调整策略
	switch {
	case latency < 5*time.Millisecond:
		// 极低延迟网络：速度优先
		return flate.BestSpeed

	case latency < 30*time.Millisecond:
		// 中等延迟：平衡模式
		return flate.DefaultCompression

	case latency < 100*time.Millisecond:
		// 较高延迟：适度提高压缩率
		return min(flate.DefaultCompression+1, flate.BestCompression)

	default:
		// 高延迟网络：最高压缩率
		return flate.BestCompression
	}
}

// ================== 集成到核心逻辑 ==================

// WriteRequest 改写为使用智能压缩
func (c *CompressedGobCodec) WriteRequest(req *rpc.Request, body interface{}) (err error) {
	c.encLock.Lock()
	defer c.encLock.Unlock()

	defer func() {
		if r := recover(); r != nil {
			log.Println(debug.Stack())
		} else {
			if err != nil {
				log.Println(err)
			}
		}
	}()

	if c == nil || c.br == nil || c.conn == nil {
		return errors.New("codec or reader not initialized")
	}

	// 获取测量开始时间
	start := time.Now()

	// 重用内存缓冲区
	buf := bufferPool.Get().(*bytes.Buffer)
	defer bufferPool.Put(buf)
	buf.Reset()

	// 创建临时编码器
	enc := newSyncEncoder(buf)
	if err = enc.Encode(req); err != nil {
		return
	}
	if err = enc.Encode(body); err != nil {
		return
	}

	// 记录编码完成时间
	encodeDuration := time.Since(start)

	// 应用智能压缩策略
	data := buf.Bytes()
	if err = c.adaptiveCompress(data); err != nil {
		return
	}

	// 更新网络延迟指标
	c.lastLatency = time.Since(start) - encodeDuration

	// 更新网络延迟统计
	c.stats.Lock()
	c.stats.lastLatency = encodeDuration
	if encodeDuration > c.stats.maxLatency {
		c.stats.maxLatency = encodeDuration
	}
	// 更新平均延迟
	if c.stats.latencySamples == 0 {
		c.stats.avgLatency = encodeDuration
	} else {
		c.stats.avgLatency = (c.stats.avgLatency*time.Duration(c.stats.latencySamples) +
			encodeDuration) / time.Duration(c.stats.latencySamples+1)
	}
	c.stats.latencySamples++
	c.stats.Unlock()

	return
}

// ================== 解码端相应调整 ==================
func (c *CompressedGobCodec) ReadResponseHeader(resp *rpc.Response) (err error) {

	var (
		start    = time.Now()
		dataSize uint32
	)
	defer func() {
		if err == nil {
			// 更新读取统计
			c.stats.Lock()
			c.stats.networkReadTime += time.Since(start)
			c.stats.networkReadBytes += uint64(headerSize + 1 + int(dataSize))
			c.stats.Unlock()
		} else {
			if err := recover(); err != nil {
				log.Println(debug.Stack())
			}
		}
	}()
	if c == nil || c.br == nil || c.conn == nil {
		return errors.New("codec or reader not initialized")
	}
	// 读取压缩标志和长度
	header := make([]byte, 5)
	if _, err = io.ReadFull(c.br, header[:]); err != nil {
		return err
	}

	isCompressed := header[0] != 0x00
	dataSize = binary.BigEndian.Uint32(header[1:])

	// 安全检查
	if dataSize > maxBufferSize {
		err = errors.New("compressed data exceeds size limit")
		return
	}

	// 创建限定读取器
	lr := io.LimitReader(c.br, int64(dataSize))

	if isCompressed {
		// 创建解压缩器
		decompressor := flate.NewReader(lr)
		defer decompressor.Close()

		// 流式Gob解码
		dec := gob.NewDecoder(decompressor)
		err = dec.Decode(resp)
		return
	}

	// 未压缩数据直接解码
	dec := gob.NewDecoder(lr)
	err = dec.Decode(resp)
	return
}

// ================== 辅助工具函数 ==================
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func (c *CompressedGobCodec) ReadResponseBody(body interface{}) error {
	return gob.NewDecoder(c.br).Decode(body)
}

// ================== 同步安全编码器包装 ==================
type syncEncoder struct {
	enc *gob.Encoder
	mu  sync.Mutex
}

func newSyncEncoder(w io.Writer) *syncEncoder {
	return &syncEncoder{
		enc: gob.NewEncoder(w),
	}
}

func (e *syncEncoder) Encode(v interface{}) error {
	e.mu.Lock()
	defer e.mu.Unlock()
	return e.enc.Encode(v)
}

// ================== 连接管理 ==================
func (c *CompressedGobCodec) Close() error {
	// 优雅关闭策略
	if err := c.bw.Flush(); err != nil {
		c.conn.Close()
		return err
	}
	return c.conn.Close()
}
